-
-
Notifications
You must be signed in to change notification settings - Fork 4
chore(deps): update pnpm to v10 [security] #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
462fc8e to
e652d7f
Compare
68e1dd8 to
96e7971
Compare
195d3f5 to
2219dd2
Compare
ae07955 to
16d25ec
Compare
b510984 to
80352be
Compare
80352be to
02d16b0
Compare
|
02d16b0 to
ec5c956
Compare
ec5c956 to
3bc0e40
Compare
d3361cd to
759c8e8
Compare
2e977c5 to
75db10d
Compare
6ffdad5 to
f8cdad7
Compare
f8cdad7 to
4767e76
Compare
This PR contains the following updates:
8.15.1→10.27.0GitHub Vulnerability Alerts
CVE-2024-53866
Summary
pnpm seems to mishandle overrides and global cache:
This can make workspace A (even running with
ignore-scripts=true) posion global cache and execute scripts in workspace BUsers generally expect
ignore-scriptsto be sufficient to prevent immediate code execution on install (e.g. when the tree is just repacked/bundled without executing it).Here, that expectation is broken
Details
See PoC.
In it, overrides from a single run of A get leaked into e.g.
~/Library/Caches/pnpm/metadata/registry.npmjs.org/rimraf.jsonand persistently affect all other projects using the cachePoC
Postinstall code used in PoC is benign and can be inspected in https://www.npmjs.com/package/ponyhooves?activeTab=code, it's just a
console.logOn mac:
rm -rf ~/Library/Caches/pnpm ~/Library/pnpm/storeThis step is not required in general, but we'll be using a popular package for PoC that's likely cached
A/package.json:{ "name": "A", "pnpm": { "overrides": { "rimraf>glob": "npm:ponyhooves@1" } }, "dependencies": { "rimraf": "6.0.1" } }pnpm i --ignore-scripts(the flag is not required, but the point of the demo is to show that it doesn't help)B/package.json:{ "name": "B", "dependencies": { "rimraf": "6.0.1" } }pnpm iResult:
Also, that code got leaked into another project and it's lockfile now!
Impact
Global state integrity is lost via operations that one would expect to be secure, enabling subsequently running arbitrary code execution on installs
As a work-around, use separate cache and store dirs in each workspace
CVE-2024-47829
The path shortening function is used in pnpm:
However, it uses the md5 function as a path shortening compression function, and if a collision occurs, it will result in the same storage path for two different libraries. Although the real names are under the package name /node_modoules/, there are no version numbers for the libraries they refer to.

In the diagram, we assume that two packages are called packageA and packageB, and that the first 90 digits of their package names must be the same, and that the hash value of the package names with versions must be the same. Then C is the package that they both reference, but with a different version number. (npm allows package names up to 214 bytes, so constructing such a collision package name is obvious.)
Then hash(packageA@1.2.3)=hash(packageB@3.4.5). This results in the same path for the installation, and thus under the same directory. Although the package names under node_modoules are the full paths again, they are shared with C.
What is the exact version number of C?
In our local tests, it depends on which one is installed later. If packageB is installed later, the C version number will change to 2.0.0. At this time, although package A requires the C@1.0.0 version, package. json will only work during installation, and will not affect the actual operation.
We did not receive any installation error issues from pnpm during our local testing, nor did we use force, which is clearly a case that can be triggered.
For a package with a package name + version number longer than 120, another package can be constructed to introduce an indirect reference to a lower version, such as one with some known vulnerability.
Alternatively, it is possible to construct two packages with more than 120 package names + version numbers.
This is clearly an advantage for those intent on carrying out supply chain attacks.
The solution:
The repair cost is also very low, just need to upgrade the md5 function to sha256.
CVE-2025-69262
Summary
A command injection vulnerability exists in pnpm when using environment variable substitution in
.npmrcconfiguration files withtokenHelpersettings. An attacker who can control environment variables during pnpm operations could achieve remote code execution (RCE) in build environments.Affected Components
@pnpm/config.env-replaceandloadTokenfunctionalitypnpm/network/auth-header/src/getAuthHeadersFromConfig.ts-loadToken()functionpnpm/config/config/src/readLocalConfig.ts-.npmrcenvironment variable substitutionTechnical Details
Vulnerability Chain
Environment Variable Substitution
.npmrcsupports${VAR}syntaxreadLocalConfig()loadToken Execution
spawnSync(helperPath, { shell: true })Attack Flow
Code Evidence
pnpm/config/config/src/readLocalConfig.ts:17-18pnpm/network/auth-header/src/getAuthHeadersFromConfig.ts:60-71Proof of Concept
Prerequisites
PoC Steps
PoC Results
Impact
Severity
Affected Environments
High Risk:
Low Risk:
Attack Scenarios
Scenario 1: CI/CD Supply Chain
Scenario 2: Docker Build
Scenario 3: Kubernetes
Mitigation
Temporary Workarounds
Disable tokenHelper:
Use direct tokens:
//registry.npmjs.org/:_authToken=YOUR_TOKENAudit environment variables:
Recommended Fixes
shell: truefrom loadTokenDisclosure
References
@pnpm/config.env-replace@^3.0.2Credit
Reported by: Jiyong Yang
Contact: sy2n0@naver.com
CVE-2025-69263
Summary
HTTP tarball dependencies (and git-hosted tarballs) are stored in the lockfile without integrity hashes. This allows the remote server to serve different content on each install, even when a lockfile is committed.
Details
When a package depends on an HTTP tarball URL, pnpm's tarball resolver returns only the URL without computing an integrity hash:
resolving/tarball-resolver/src/index.ts:The resulting lockfile entry has no integrity to verify:
Since there is no integrity hash, pnpm cannot detect when the server returns different content.
This affects:
"pkg": "https://example.com/pkg.tgz")"pkg": "github:user/repo")"pkg": "git+https://github.com/user/repo")npm registry packages are not affected as they include integrity hashes from the registry metadata.
PoC
See attached pnpm-bypass-integrity-poc.zip
The POC includes:
malicious-packagethat depends on the HTTP tarballvictimproject that depends onmalicious-packageTo run:
cd pnpm-bypass-integrity-poc ./run-poc.shThe output shows that each install (with
pnpm store prunebetween them) downloads different code despite having a committed lockfile.Impact
An attacker who publishes a package with an HTTP tarball dependency can serve different code to different users or CI/CD environments. This enables:
The attack requires the victim to install a package that has an HTTP/git tarball in its dependency tree. The victim's lockfile provides no protection.
Release Notes
pnpm/pnpm (pnpm)
v10.27.0Compare Source
v10.26.2: pnpm 10.26.2Compare Source
Patch Changes
Improve error message when a package version exists but does not meet the
minimumReleaseAgeconstraint. The error now clearly states that the version exists and shows a human-readable time since release (e.g., "released 6 hours ago") #10307.Fix installation of Git dependencies using annotated tags #10335.
Previously, pnpm would store the annotated tag object's SHA in the lockfile instead of the actual commit SHA. This caused
ERR_PNPM_GIT_CHECKOUT_FAILEDerrors because the checked-out commit hash didn't match the stored tag object hash.Binaries of runtime engines (Node.js, Deno, Bun) are written to
node_modules/.binbefore lifecycle scripts (install, postinstall, prepare) are executed #10244.Try to avoid making network calls with preferOffline #10334.
Platinum Sponsors
Gold Sponsors
v10.26.1: pnpm 10.26.1Compare Source
Patch Changes
pnpm add, whenblockExoticSubdepsis set totrue#10324.HEADpoints to the commit after checkout #10310.Platinum Sponsors
Gold Sponsors
v10.26.0Compare Source
v10.25.0Compare Source
v10.24.0Compare Source
v10.23.0: pnpm 10.23Compare Source
Minor Changes
--lockfile-onlyoption topnpm list#10020.Patch Changes
pnpm self-updateshould download pnpm from the configured npm registry #10205.pnpm self-updateshould always install the non-executable pnpm package (pnpm in the registry) and never the@pnpm/exepackage, when installing v11 or newer. We currently cannot ship@pnpm/exeaspkgdoesn't work with ESM #10190.pnpm add, if there's aengines.runtimesetting declared inpackage.json#10209.pnpm listandpnpm whynow display npm: protocol for aliased packages (e.g.,foo npm:is-odd@3.0.1) #8660.pnpm store pruneshould not fail if the store contains Node.js packages #10131.Platinum Sponsors
Gold Sponsors
v10.22.0: pnpm 10.22Compare Source
Minor Changes
Added support for
trustPolicyExclude#10164.You can now list one or more specific packages or versions that pnpm should allow to install, even if those packages don't satisfy the trust policy requirement. For example:
Allow to override the
enginesfield on publish by thepublishConfig.enginesfield.Patch Changes
Platinum Sponsors
Gold Sponsors
v10.21.0Compare Source
v10.20.0Compare Source
Minor Changes
--alloption inpnpm --helpto list all commands #8628.Patch Changes
latestversion doesn't satisfy the maturity requirement configured byminimumReleaseAge, pick the highest version that is mature enough, even if it has a different major version #10100.createcommand should not verify patch info.managePackageManagerVersionstofalse, when switching to a different version of pnpm CLI, in order to avoid subsequent switches #10063.v10.19.0Compare Source
Minor Changes
You can now allow specific versions of dependencies to run postinstall scripts.
onlyBuiltDependenciesnow accepts package names with lists of trusted versions. For example:Related PR: #10104.
Added support for exact versions in
minimumReleaseAgeExclude#9985.You can now list one or more specific versions that pnpm should allow to install, even if those versions don’t satisfy the maturity requirement set by
minimumReleaseAge. For example:v10.18.3Compare Source
Patch Changes
verifyDepsBeforeInstall: installand pre/post install scripts that called other pnpm scripts #10060.@scope:registry) being parsed as property paths inpnpm config getwhen--location=projectis used #9362.pnpm config set --location=projectincorrectly handling keys with slashes (auth tokens, registry settings) #9884.pnpm-workspace.yamland.npmrcexist,pnpm config set --location=projectnow writes topnpm-workspace.yaml(matching read priority) #10072.pnpm outdated --long#10040.v10.18.2Compare Source
Patch Changes
pnpm outdated --longshould work #10040.pnpm dlxshould request the full metadata of packages, whenminimumReleaseAgeis set #9963.EPIPEerrors when piping output to other commands #10027.v10.18.1Compare Source
Patch Changes
--lockfile-onlyis used #8320.pnpm setupcreates a command shim to the pnpm executable. This is needed to be able to runpnpm self-updateon Windows #5700.pnpm install, pnpm produced false positive warnings for "skip adding to the default catalog because it already exists". This warning now only prints when usingpnpm add --save-catalogas originally intended.v10.18.0Compare Source
Minor Changes
Added network performance monitoring to pnpm by implementing warnings for slow network requests, including both metadata fetches and tarball downloads.
Added configuration options for warning thresholds:
fetchWarnTimeoutMsandfetchMinSpeedKiBps.Warning messages are displayed when requests exceed time thresholds or fall below speed minimums
Related PR: #10025.
Patch Changes
minimumReleaseAgeconfiguration #10030.cleanupUnusedCatalogsconfiguration when removing dependent packages.scriptShellis set tofalse#8748.pnpm dlxshould not fail whenminimumReleaseAgeis set #10037.v10.17.1Compare Source
Patch Changes
minimumReleaseAgesetting, print this information out in the error message #9974.state.jsoncreation path when executingpnpm patchin a workspace project #9733.minimumReleaseAgeis set and thelatesttag is not mature enough, prefer a non-deprecated version as the newlatest#9987.v10.17.0Compare Source
Minor Changes
The
minimumReleaseAgeExcludesetting now supports patterns. For instance:Related PR: #9984.
Patch Changes
minimumReleaseAgecheck, when the package is requested by exact version and the packument is loaded from cache #9978.minimumReleaseAgeis set and the active version under a dist-tag is not mature enough, do not downgrade to a prerelease version in case the original version wasn't a prerelease one #9979.v10.16.1Compare Source
Patch Changes
v10.16.0Compare Source
Minor Changes
There have been several incidents recently where popular packages were successfully attacked. To reduce the risk of installing a compromised version, we are introducing a new setting that delays the installation of newly released dependencies. In most cases, such attacks are discovered quickly and the malicious versions are removed from the registry within an hour.
The new setting is called
minimumReleaseAge. It specifies the number of minutes that must pass after a version is published before pnpm will install it. For example, settingminimumReleaseAge: 1440ensures that only packages released at least one day ago can be installed.If you set
minimumReleaseAgebut need to disable this restriction for certain dependencies, you can list them under theminimumReleaseAgeExcludesetting. For instance, with the following configuration pnpm will always install the latest version of webpack, regardless of its release time:Related issue: #9921.
Added support for
finders#9946.In the past,
pnpm listandpnpm whycould only search for dependencies by name (and optionally version). For example:prints the chain of dependencies to any installed instance of
minimist:What if we want to search by other properties of a dependency, not just its name? For instance, find all packages that have
react@17in their peer dependencies?This is now possible with "finder functions". Finder functions can be declared in
.pnpmfile.cjsand invoked with the--find-by=<function name>flag when runningpnpm listorpnpm why.Let's say we want to find any dependencies that have React 17 in peer dependencies. We can add this finder to our
.pnpmfile.cjs:Now we can use this finder function by running:
pnpm will find all dependencies that have this React in peer dependencies and print their exact locations in the dependency graph.
It is also possible to print out some additional information in the output by returning a string from the finder. For example, with the following finder:
Every matched package will also print out the license from its
package.json:Patch Changes
nodeVersionis not set to an exact semver version #9934.pnpm publishshould be able to publish a.tar.gzfile #9927.pnpm runreturn a non-zero exit code #9626.v10.15.1Compare Source
Patch Changes
.pnp.cjscrash when importing subpath #9904.v10.15.0Compare Source
Minor Changes
cleanupUnusedCatalogsconfiguration. When set totrue, pnpm will remove unused catalog entries during installation #9793.@*/pnpm-plugin-*#9780.pnpm config getnow prints an INI string for an object value #9797.pnpm config getnow accepts property paths (e.g.pnpm config get catalog.react,pnpm config get .catalog.react,pnpm config get 'packageExtensions["@​babel/parser"].peerDependencies["@​babel/types"]'), andpnpm config setnow accepts dot-leading or subscripted keys (e.g.pnpm config set .ignoreScripts true).pnpm config get --jsonnow prints a JSON serialization of config value, andpnpm config set --jsonnow parses the input value as JSON.Patch Changes
pnpm createcommand, must verify whether the node version is supported even if a cache already exists #9775.*/*to theAcceptheader to avoid getting a 406 error on AWS CodeArtifact #9862.pnpm dlx pkg --helpdoesn't pass--helptopkg#9823.v10.14.0Compare Source
Minor Changes
Added support for JavaScript runtime resolution
Declare Node.js, Deno, or Bun in
devEngines.runtime(insidepackage.json) and let pnpm download and pin it automatically.Usage example:
{ "devEngines": { "runtime": { "name": "node", "version": "^24.4.0", "onFail": "download" (we only support the "download" value for now) } } }How it works:
pnpm installresolves your specified range to the latest matching runtime version.Why this is better:
useNodeVersionandexecutionEnv.nodeVersion)executionEnv.nodeVersion). So, different projects in a workspace can use different runtimes.devEngines.runtimesetting will install the runtime locally, which we will improve in future versions of pnpm by using a shared location on the computer.Related PR: #9755.
Add
--cpu,--libc, and--ostopnpm install,pnpm add, andpnpm dlxto customizesupportedArchitecturesvia the CLI #7510.Patch Changes
pnpm adddownloads packages whoselibcdiffer frompnpm.supportedArchitectures.libc.dlxto parse CLI flags and options between thedlxcommand and the command to run or between thedlxcommand and--#9719.pnpm install --prodshould removing hoisted dev dependencies #9782.pnpm installto incorrectly assume the lockfile is up to date after changing a local tarball that has peers dependencies.v10.13.1Compare Source
Patch Changes
v10.13.0Compare Source
Minor Changes
Added the possibility to load multiple pnpmfiles. The
pnpmfilesetting can now accept a list of pnpmfile locations #9702.pnpm will now automatically load the
pnpmfile.cjsfile from any config dependency named@pnpm/plugin-*orpnpm-plugin-*#9729.The order in which config dependencies are initialized should not matter — they are initialized in alphabetical order. If a specific order is needed, the paths to the
pnpmfile.cjsfiles in the config dependencies can be explicitly listed using thepnpmfilesetting inpnpm-workspace.yaml.Patch Changes
pkg.pr.new, treat them as Git tarball URLs #9694.dangerouslyAllowAllBuilds,onlyBuiltDependencies,onlyBuiltDependenciesFile, andneverBuiltDependencies#9628.pnpm-workspace.yamlwith deep #9701.pnpm rebuildcommand should not add pkgs included inignoredBuiltDependenciestoignoredBuildsinnode_modules/.modules.yaml#9338.shell-quotewithshlexfor quoting command arguments #9381.v10.12.4Compare Source
Patch Changes
Fix
pnpm licensescommand for local dependencies #9583.Fix a bug in which
pnpm ls --filter=not-exist --jsonprints nothing instead of an empty array #9672.Fix a deadlock that sometimes happens during peer dependency resolution #9673.
Running
pnpm installafterpnpm fetchshould hoist all dependencies that need to be hoisted.Fixes a regression introduced in [v10.12.2] by [#9648]; resolves [#9689].
[v10.12.2]: https://github.com/pnpm/pnpm/releases/tag/v10.12.2Add commentMore actions
[#9648]: #9648
[#9689]: #9689
v10.12.3Compare Source
Patch Changes
Regression introduced in v10.12.2 by #9648; resolves #9685.
v10.12.2Compare Source
Patch Changes
enableGlobalVirtualStoreset totrue#9648.--helpand-hflags not working as expected for thepnpm createcommand.pnpm licenses list --jsoncommand is incorrect.pnpm deployfails due to overridden dependencies having peer dependencies causingERR_PNPM_OUTDATED_LOCKFILE#9595.v10.12.1Minor Changes
Experimental. Added support for global virtual stores. When enabled,
node_modulescontains only symlinks to a central virtual store, rather tonode_modules/.pnpm. By default, this central store is located at<store-path>/links(you can find the store path by runningpnpm store path).In the central virtual store, each package is hard linked into a directory whose name is the hash of its dependency graph. This allows multiple projects on the system to symlink shared dependencies from this central location, significantly improving installation speed when a warm cache is available.
To enable the global virtual store, set
enableGlobalVirtualStore: truein your rootpnpm-workspace.yaml, or globally via:NOTE: In CI environments, where caches are typically cold, this setting may slow down installation. pnpm automatically disables the global virtual store when running in CI.
Related PR: #8190
pnpm updatecommand now supports updatingcatalog:protocol dependencies and writes new specifiers topnpm-workspace.yaml.--save-catalogand--save-catalog-name=<name>) topnpm addto save new dependencies as catalog entries.catalog:orcatalog:<name>will be added topackage.jsonand the package specifier will be added to thecatalogsorcatalog[<name>]object inpnpm-workspace.yaml#9425.cifor explicitly telling pnpm if the current environment is a CI or not.Patch Changes
pnpm patchusing semantic versioning rules.v10.11.1Compare Source
Patch Changes
pnpm deploy --legacycreates unexpected directories when the rootpackage.jsonhas a workspace package as a peer dependency #9550.strictPeerDependenciesistruebut all issues are ignored bypeerDependencyRules#9505.pnpm_config_env variables instead ofnpm_config_#9571.--lockfile-onlyflag onpnpm updateto produce a differentpnpm-lock.yamlthan an update without the flag.pnpm deploywork in repos withoverrideswheninject-workspace-packages=true#9283.pnpm -r --silent runshould not print out section #9563.v10.11.0Compare Source
Minor Changes
A new setting added for
pnpm initto create apackage.jsonwithtype=module, wheninit-typeismodule. Works as a flag for the init command too #9463.Added support for Nushell to
pnpm setup#6476.Added two new flags to the
pnpm auditcommand,--ignoreand--ignore-unfixable#8474.Ignore all vulnerabilities that have no solution:
> pnpm audit --ignore-unfixableProvide a list of CVE's to ignore those specifically, even if they have a resolution.
> pnpm audit --ignore=CVE-2021-1234 --ignore=CVE-2021-5678Added support for recursively running pack in every project of a workspace #4351.
Now you can run
pnpm -r packto pack all packages in the workspace.Patch Changes
dangerouslyAllowAllBuildsis set totrue#9472.pnpm linkshould work from inside a workspace #9506.workspaceConcurrencyto `Math.min(oConfiguration
📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
This PR was generated by Mend Renovate. View the repository job log.